/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package czStvDpds.input;

import czStvDpds.logging.Logging;
import java.util.ArrayList;
import java.util.logging.Level;
import org.lwjgl.input.Mouse;

/**
 * Stará se o zjišťování akcí myši. Běží v samostatném vlákně. Funguje pouze
 * pokud je aktivní okno LWJGL. Pokud není, ukočí se poslouchání.
 *
 * @author divad
 */
public class MouseHandler extends Thread {

    private long delay = 15;
    private ArrayList<LWJGLMouseListener> listeners;
    private boolean running;

    /**
     * vytvoří novou instanci a spustí zjišťovací vlákno
     */
    public MouseHandler() {
        listeners = new ArrayList<>();
        this.running = false;
//        this.start();
    }

    /**
     * vytvoří novou instanci s předanými posluchači a spustí zjišťovací vlákno
     */
    private MouseHandler(ArrayList<LWJGLMouseListener> listeners, long delay) {
        this.listeners = listeners;
        this.delay = delay;
        this.start();
        this.running = true;
    }

    /**
     * Přidá listener do seznamu posluchačů.
     *
     * @param listener
     * @see LWJGLMouseListener
     */
    public void addLWJGLMouseListener(LWJGLMouseListener listener) {
        this.listeners.add(listener);
    }

    /**
     * odebere listener ze seznamu posluchačů
     *
     * @param listener
     * @see LWJGLMouseListener
     */
    public void removeLWJGLMouseListener(LWJGLMouseListener listener) {
        this.listeners.remove(listener);
    }

    /**
     * vrátí pole předaných posluchačů
     *
     * @return
     * @see LWJGLMouseListener
     */
    public ArrayList<LWJGLMouseListener> getLWJGLMouseListeners() {
        return listeners;
    }

    /**
     * Nastaví dobu mezi jednotlivými pokusy o přečtení v stupů v milisekundách
     *
     * @param delay
     */
    public void setDelay(long delay) {
        this.delay = delay;
    }

    /**
     * Vrátí dobu mezi jednotlivými pokusy o přečtení v milisekundách
     *
     * @return
     */
    public long getDelay() {
        return delay;
    }

    /**
     * Ukončí poslouchací vlákno. Toto vlákno již nelze zpětně rozběhnout.
     */
    public void stopListening() {
        this.running = false;
    }

    /**
     * Vrátí nový MouseHandler s předanými posluchači
     */
    public MouseHandler startListening() {
        this.running = false;
        return new MouseHandler(this.listeners, this.delay);
    }

    /**
     * Čte akce myši a předává je předaným listenerům. Každý předávaný event
     * reprezentuje </b>jednu</b> akci myši - tzn. v jednom eventu nebude
     * zároveň informace o stisku tlačítka a pohybu myši atd.
     */
    @Override
    public void run() {
//        boolean nextPrint = false;
        while (Mouse.isCreated() && this.running) {
            while (Mouse.next()) {
//                nextPrint = true;
                LWJGLMouseEvent e = new LWJGLMouseEvent(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDX(), Mouse.getEventDY(), Mouse.getEventX(), Mouse.getEventY(), Mouse.getEventDWheel(), Mouse.getEventNanoseconds());
                for (LWJGLMouseListener l : listeners) {
                    l.mouseAction(e);
                }
            }
//            if (nextPrint) {
//                System.out.println("*******************************");
//                nextPrint = false;
//            }
            try {
                this.sleep(delay);
            } catch (InterruptedException ex) {
                Logging.getMainLogger().log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("Mouse listening terminated");
        this.running = false;
    }

    public boolean isRunning() {
        return running;
    }
}
